/*
* Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "usb_connection_notifier.h"

#include <parameters.h>
#include "hilog_wrapper.h"
#include "want_agent_info.h"
#include "want_agent_helper.h"
#include "notification_normal_content.h"
#include "resource_manager.h"
#include "locale_config.h"
#include "locale_info.h"
#include "string_wrapper.h"
#include "iservice_registry.h"
#include "bundle_mgr_interface.h"
#include "system_ability_definition.h"
#include "image_source.h"
#include "os_account_manager.h"
#include "usb_errors.h"

using namespace OHOS::AAFwk;

const std::string NOTIFICATION_NAME = "usb_service";
constexpr int32_t USB_SERVICE_UID = 1018;
const std::string BUNDLE_NAME = "com.huawei.hmos.settings";
const std::string BUNDLE_NAME_KEY = "com.huawei.hmos.settings.MainAbility";
const std::string URI = "enhance_netmanager";
const std::string HAP_PATH = "/system/app/usb_right_dialog/usb_right_dialog.hap";

namespace OHOS {
namespace USB {
namespace {
} // namespace
class NfcNotificationSubscriber : public Notification::NotificationSubscriber {
    void OnConnected()
    {
        USB_HILOGI(MODULE_USB_SERVICE, "%{public}s", __func__);
    }
    void OnDisconnected()
    {
        USB_HILOGI(MODULE_USB_SERVICE, "%{public}s", __func__);
    }
    void OnUpdate(const std::shared_ptr<Notification::NotificationSortingMap> &sortingMap)
    {
        USB_HILOGI(MODULE_USB_SERVICE, "%{public}s", __func__);
    }
    void OnDoNotDisturbDateChange(const std::shared_ptr<Notification::NotificationDoNotDisturbDate> &date)
    {
        USB_HILOGI(MODULE_USB_SERVICE, "%{public}s", __func__);
    }
    void OnEnabledNotificationChanged(
        const std::shared_ptr<Notification::EnabledNotificationCallbackData> &callbackData)
    {
        USB_HILOGI(MODULE_USB_SERVICE, "%{public}s", __func__);
    }
    void OnDied()
    {
        USB_HILOGI(MODULE_USB_SERVICE, "%{public}s", __func__);
    }
    void OnCanceled(const std::shared_ptr<OHOS::Notification::Notification> &request,
        const std::shared_ptr<Notification::NotificationSortingMap> &sortingMap, int deleteReason)
    {
        USB_HILOGI(MODULE_USB_SERVICE, "%{public}s", __func__);
    }
    void OnConsumed(const std::shared_ptr<OHOS::Notification::Notification> &notification,
        const std::shared_ptr<Notification::NotificationSortingMap> &sortingMap)
    {
        USB_HILOGI(MODULE_USB_SERVICE, "%{public}s", __func__);
    }
    void OnBadgeChanged(const std::shared_ptr<Notification::BadgeNumberCallbackData> &badgeData)
    {
        USB_HILOGI(MODULE_USB_SERVICE, "%{public}s", __func__);
    }
    void OnBadgeEnabledChanged(const sptr<Notification::EnabledNotificationCallbackData> &callbackData)
    {
        USB_HILOGI(MODULE_USB_SERVICE, "%{public}s", __func__);
    }
    void OnBatchCanceled(const std::vector<std::shared_ptr<OHOS::Notification::Notification>> &requestList,
        const std::shared_ptr<Notification::NotificationSortingMap> &sortingMap, int32_t deleteReason)
    {
        USB_HILOGI(MODULE_USB_SERVICE, "%{public}s", __func__);
    }
};

static std::shared_ptr<NfcNotificationSubscriber> g_notificationSubscriber
    = std::make_shared<NfcNotificationSubscriber>();

std::shared_ptr<UsbConnectionNotifier> UsbConnectionNotifier::instance_;

std::shared_ptr<UsbConnectionNotifier> UsbConnectionNotifier::GetInstance()
{
    if (instance_ == nullptr) {
        USB_HILOGI(MODULE_USB_SERVICE, "%{public}s: reset to new instance", __func__);
        instance_.reset(new UsbConnectionNotifier());
    }
    return instance_;
}

UsbConnectionNotifier::UsbConnectionNotifier()
{
    GetHapString();
    int32_t result = Notification::NotificationHelper::SubscribeNotification(*g_notificationSubscriber);
    USB_HILOGI(MODULE_USB_SERVICE, "%{public}s: result %{public}d", __func__, result);
}

UsbConnectionNotifier::~UsbConnectionNotifier() {}

void UsbConnectionNotifier::GetHapString()
{
    USB_HILOGI(MODULE_USB_SERVICE, "%{public}s", __func__);
    std::shared_ptr<Global::Resource::ResourceManager> resourceManager(Global::Resource::CreateResourceManager());
    if (resourceManager == nullptr) {
        USB_HILOGE(MODULE_USB_SERVICE, "resourceManager is null");
        return;
    }
    std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
    if (resConfig == nullptr) {
        USB_HILOGE(MODULE_USB_SERVICE, "resConfig is null");
        return;
    }
    std::map<std::string, std::string> configs;
    OHOS::Global::I18n::LocaleInfo locale(Global::I18n::LocaleConfig::GetSystemLocale(), configs);
    resConfig->SetLocaleInfo(locale.GetLanguage().c_str(), locale.GetScript().c_str(), locale.GetRegion().c_str());
    resourceManager->UpdateResConfig(*resConfig);
    if (!resourceManager->AddResource(HAP_PATH.c_str())) {
        USB_HILOGE(MODULE_USB_SERVICE, "AddResource failed");
        return;
    }
    for (auto it : notifierMap) {
        std::string outValue;
        resourceManager->GetStringByName(it.first.c_str(), outValue);
        notifierMap[it.first] = outValue;
    }
    return;
}

void UsbConnectionNotifier::SetWantAgent(OHOS::Notification::NotificationRequest &request)
{
    auto want = std::make_shared<AAFwk::Want>();
    want->SetElementName(BUNDLE_NAME, BUNDLE_NAME_KEY);
    want->SetFlags(AAFwk::Want::FLAG_AUTH_READ_URI_PERMISSION);
    want->SetUri(URI);
    std::vector<std::shared_ptr<AAFwk::Want>> wants;
    wants.push_back(want);

    std::vector<AbilityRuntime::WantAgent::WantAgentConstant::Flags> flags;
    flags.push_back(AbilityRuntime::WantAgent::WantAgentConstant::Flags::CONSTANT_FLAG);

    AbilityRuntime::WantAgent::WantAgentInfo wantAgentInfo(
        0, AbilityRuntime::WantAgent::WantAgentConstant::OperationType::START_ABILITY, flags, wants, nullptr);
    auto wantAgent = AbilityRuntime::WantAgent::WantAgentHelper::GetWantAgent(wantAgentInfo);
    request.SetWantAgent(wantAgent);
}

void UsbConnectionNotifier::SendNotification(std::string func)
{
    USB_HILOGI(MODULE_USB_SERVICE, "%{public}s: func %{public}s", __func__, func.c_str());

    std::shared_ptr<OHOS::Notification::NotificationNormalContent> normalContent =
        std::make_shared<OHOS::Notification::NotificationNormalContent>();
    normalContent->SetTitle(notifierMap[func]);
    normalContent->SetText(notifierMap[func]);
    std::shared_ptr<OHOS::Notification::NotificationContent> content =
        std::make_shared<OHOS::Notification::NotificationContent>(normalContent);

    request_.SetNotificationId(std::hash<std::string>()(std::string(NOTIFICATION_NAME)));
    request_.SetContent(content);
    request_.SetCreatorUid(USB_SERVICE_UID);
    request_.SetUnremovable(true);
    request_.SetRemoveAllowed(true);
    request_.SetTapDismissed(false);
    SetWantAgent(request_);
    int32_t result = OHOS::Notification::NotificationHelper::PublishNotification(request_);
    USB_HILOGI(MODULE_USB_SERVICE, "PublishNotification result : %{public}d", result);
}

void UsbConnectionNotifier::CancelNotification()
{
    USB_HILOGI(MODULE_USB_SERVICE, "%{public}s", __func__);
    int32_t notificationId = request_.GetNotificationId();
    int32_t result = OHOS::Notification::NotificationHelper::CancelNotification(notificationId);
    USB_HILOGI(MODULE_USB_SERVICE, "%{public}s: notificationId %{public}d, result %{public}d", __func__,
        notificationId, result);
}
} // namespace USB
} // namespace OHOS